import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * @author suoyue_zhan
 * @date 2021/03/12 10:02
 * @descript 集合转数组
 */
public class CollectionAndArray {

    public static void main(String[] args) {
        ColToArray();
        System.out.println("\n============================");
        arraysAsList();
        System.out.println("============================");
        forEachIterator();
    }

    /**
     * 集合转数组
     * 使用 toArray 带参方法，数组空间大小的 length
     * 1） 等于 0，动态创建与 size 相同的数组，性能最好。
     * 2） 大于 0 但小于 size，重新创建大小等于 size 的数组，增加 GC 负担。
     * 3） 等于 size，在高并发情况下，数组创建完成之后，size 正在变大的情况下，负面影响与 2 相同。
     * 4） 大于 size，空间浪费，且在 size 处插入 null 值，存在 NPE 隐患。
     */
    public static void ColToArray(){
        List<String> list = new ArrayList<>(2);
        list.add("suoyue");
        list.add("zhan");

        //直接使用 toArray 无参方法返回值只能是 Object[]类，若强转其它类型数组将出现ClassCastException错误
        Object[] listArray = list.toArray();
        for (Object listArr : listArray) {
            System.out.print(listArr+"\t");
        }

        System.out.println();
        //推荐：使用集合转数组的方法，必须使用集合的 toArray(T[] array)，传入的是类型完全一致、长度为 0 的空数组
        String[] array = list.toArray(new String[0]);
        for (String arr : array) {
            System.out.print(arr+"\t");
        }
    }


    /**
     * 使用工具类 Arrays.asList()把数组转换成集合时，不能使用其修改集合相关的方法(add/remove/clear),会抛出UnsupportedOperationException 异常。
     * 说明：asList 的返回对象是一个 Arrays 内部类，并没有实现集合的修改方法。
     * Arrays.asList体现的是适配器模式，只是转换接口，后台的数据仍是数组。
     */
    public static void arraysAsList(){
        String[] str = new String[] { "suoyue", "zhan" };
        List list = Arrays.asList(str);
        System.out.println(list);
        //运行时异常
        //list.add("bug");
        //修改数组，对应转化的list也会随之修改
        str[0] = "SUOYUE";
        System.out.println(list.get(0));
    }

    /**
     * 不要在 foreach 循环里进行元素的 remove/add 操作。
     * remove 元素请使用迭代器Iterator方式，如果并发操作，需要对 Iterator 对象加锁
     */
    public static void forEachIterator(){
        List<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("3");
        System.out.println(list);

        //Iterator执行remove操作
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String item = iterator.next();
            if ("1".equals(item)) {     //删除元素的条件
                iterator.remove();
            }
        }

        System.out.println(list);

        //foreach循环里进行remove操作,当删除的是最后一个元素时会抛并发修改异常ConcurrentModificationException
        //单步调试可观察到，当删除最后一个元素后会再次尝试进入循环，此时抛出异常
        for (String item : list) {
            if ("3".equals(item)) {
                list.remove(item);
            }
        }
        System.out.println(list);
    }


}
